<template>
  <EcDialog v-model="dialogVisible" :auto-height="true" class="form-dialog">
    <!-- 标题 -->
    <template #title>
      <div class="dialog-title">
        <SvgIcon :icon="dialogIconMap[dialogMode]" size="16" style="margin-right: 5px;"></SvgIcon>
        <span>{{ dialogModeMap[dialogMode] + ' - ' + dialogTitle }}</span>
      </div>
    </template>

    <!-- 表单数据 -->
    <el-form ref="formRef"
             v-loading="dataLoading"
             :disabled="readonly"
             :model="formData"
             :rules="formRules"
             class="full-form"
             label-width="100px"
             status-icon>

      <el-form-item label="账号：" prop="account">
        <el-input v-model="formData.account" placeholder="请输入账号" show-word-limit/>
      </el-form-item>

      <el-form-item label="昵称：" prop="nickname">
        <el-input v-model="formData.nickname" placeholder="请输入昵称"/>
      </el-form-item>

      <el-form-item :prop="isCreate ? 'password' : ''" label="登陆密码：">
        <el-input v-model="formData.password" placeholder="请输入登陆密码"/>
      </el-form-item>

      <el-form-item label="支付密码：">
        <el-input v-model="formData.pay_password" maxlength="6" placeholder="请输入支付密码" show-word-limit/>
      </el-form-item>

      <el-form-item v-if="dialogMode == 2" label="用户头像：">
        <UploadImage v-model="formData.avatar_url" :disabled="readonly" :show-delete="true"/>
      </el-form-item>

      <el-form-item v-if="showAddress" label="归属区域：">
        <AddressSelect ref="addressSelect"
                       :city-code="formData.city_code"
                       :county-code="formData.county_code"
                       :province-code="formData.province_code"
                       :readonly="readonly"
                       @change="handleChangeLocation"/>
      </el-form-item>

      <el-form-item v-if="isCreate" label="邀请码：">
        <el-input v-model="formData.invite_code" placeholder="请输入邀请人账号或邀请码" show-word-limit/>
      </el-form-item>

    </el-form>

    <!-- 底部操作区域 -->
    <template #footer>
      <span class="dialog-footer">
        <el-button :loading="dataLoading" @click="dialogVisible = false">取 消</el-button>
        <el-button v-if="!readonly" v-permission="['api:user:create', 'api:user:update']" :loading="dataLoading" type="primary" @click="onSubmitForm()">确 定</el-button>
      </span>
    </template>
  </EcDialog>
</template>

<script lang="ts" setup>
import { computed, reactive, ref } from 'vue';
import { ElLoading, ElMessage, ElNotification, FormInstance, FormRules } from 'element-plus';
import { EcDialog } from '@/components/dialog';
import { UploadImage } from '@/components/upload';
import { SvgIcon } from '@/components/icon';
import useDialog from '@/hooks/use-dialog.ts';
import { accountRegex, nicknameRegex } from '@/utils/validate.ts';
import { userInfo, userSaveOrUpdate } from '@/api/api-user.ts';
import { AddressSelect } from '@/components/other';

defineOptions({name: 'user-form'})

const formRef = ref<FormInstance>();
const formLoading = ref(false);// 表单是否加载中
const {dialogVisible, dialogTitle, dialogMode, dialogModeMap, dialogIconMap} = useDialog(false);

// 默认表单数据
let defaultForm = {
  id: 0,
  account: undefined,
  password: undefined,
  pay_password: undefined,
  nickname: undefined,
  avatar_url: undefined,
  invite_code: undefined,
  province_code: undefined,
  city_code: undefined,
  county_code: undefined,
};

// 表单数据
const formData = ref({...defaultForm});
const showAddress = ref(false);
const validateNickname = (rule: any, value: any, callback: any) => {
  if (value == null || value === '') {
    return callback(new Error('昵称不能为空'))
  } else if (!nicknameRegex.test(value)) {
    return callback(new Error('昵称格式不正确'))
  }
  let length = value.replace(/[\u0391-\uFFE5]/g, 'aa').length
  if (length < 4 || length > 30) {
    return callback(new Error('昵称长度必须在 4 - 30 个字符之间'))
  } else {
    return callback()
  }
}

// 表单验证规则
const formRules = reactive<FormRules>({
  account: [{required: true, message: '账号不能为空', trigger: 'change'}, {pattern: accountRegex, message: '账号格式不正确', trigger: 'blur'}],
  nickname: [{required: true, message: '昵称不能为空', trigger: 'change'}, {validator: validateNickname, trigger: 'change'}],
  password: [{required: true, message: '请输入登陆密码', trigger: 'blur'}, {min: 6, max: 20, message: '长度在 6 到 20 个字符', trigger: 'blur'}],
  pay_password: [{required: true, message: '请输入支付密码', trigger: 'blur'}, {min: 6, max: 6, message: '长度在 6 个字符', trigger: 'blur'}]
});

/** 判断数据是否处于加载中 */
const dataLoading = computed(() => {
  return formLoading.value;
})

/** 是否只读 */
const readonly = computed(() => {
  return dialogMode.value == 0;
});

/** 是否新增 */
const isCreate = computed(() => {
  return dialogMode.value == 1 || formData.value.id <= 0;
});

/** 打开弹窗 */
const open = async (mode: number, id?: number) => {
  dialogMode.value = mode;
  dialogTitle.value = '用户';
  dialogVisible.value = true;
  // 重置表单
  handleFormReset();

  // 加载数据
  if (id) {
    formLoading.value = true
    try {
      // 加载用户数据
      const {data} = await userInfo(id)
      formData.value = data.info;
      formData.value.password = undefined;
      formData.value.pay_password = undefined;

      // 地区显示处理
      let countyCode = formData.value.county_code
      if (!countyCode || countyCode <= 0) {
        formData.value.province_code = undefined;
        formData.value.city_code = undefined;
        formData.value.county_code = undefined;
      }
      showAddress.value = true;
    } finally {
      formLoading.value = false
    }
  } else {
    showAddress.value = true;
  }
}
// 提供 open 方法，用于打开弹窗
defineExpose({open})

/** 表单提交 */
const emit = defineEmits(['refresh']);
const onSubmitForm = async () => {
  await formRef.value?.validate((valid, fields) => {
    if (!valid) {
      ElMessage({type: 'error', message: '请检查是否有必填项未完善',});
      return
    }
    const loading = ElLoading.service({
      lock: true,
      text: '正在提交中...',
      background: 'rgba(0, 0, 0, 0.2)'
    })
    // 提交数据
    userSaveOrUpdate(formData.value, isCreate.value).then(response => {
      // 提示信息
      ElNotification({title: '成功', message: '操作完成', type: 'success', duration: 2000})
      // 发送操作成功的事件
      emit('refresh')
      // 隐藏窗口
      dialogVisible.value = false
    }).finally(() => loading.close())

  });
};

/** 地区被改变 */
const handleChangeLocation = (data: any) => {
  formData.value.province_code = data.province_code;
  formData.value.city_code = data.city_code;
  formData.value.county_code = data.county_code;
};

/** 重置表单 */
const handleFormReset = () => {
  showAddress.value = false;
  // 重置表单数据
  formData.value = {...defaultForm};
  // 重置界面表单数据
  formRef.value?.resetFields();
};

</script>

<style lang="scss" scoped>

</style>
